/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include <matXX.h>

#include "ui颜色.h"
#include "ui数值部件.h"
#include "..\UI.h"


C_拾色盘* C_颜色拾取器::g_色盘 = nullptr;
static C_颜色拾取器* g当前打开列表组件 = nullptr;



static Inline S_RGBA8UI f_vec3_to_RGBA(const vec3& v) {
	S_RGBA8UI color;
	color.r = v.x * 255;
	color.g = v.y * 255;
	color.b = v.z * 255;
	color.a = 255;
	return color;
}



static vec3 f_坐标转颜色(const C_拾色盘* self, const vec2& pos, const vec2& 轮盘组件大小) {
	vec2 size = 轮盘组件大小 * 0.5f;
	vec2 coord;
	coord.x = (pos.x - size.x) / size.x;
	coord.y = (pos.y - size.y) / size.y;
	

	float dir = 1 - vec_normalize(&coord);

	float angleB = f_graph_两向量夹角弧度180(coord, cw_V0);
	float angleG = f_graph_两向量夹角弧度180(coord, cw_V1);
	float angleR = f_graph_两向量夹角弧度180(coord, cw_V2);
	
	float nr = DEF_Max(0, 2.0943 - angleR) / 1.04719;
	float ng = DEF_Max(0, 2.0943 - angleG) / 1.04719;
	float nb = DEF_Max(0, 2.0943 - angleB) / 1.04719;


	vec3 outColor = {};
	if (angleR < 1.04719) {
		outColor = mix({ 1, 0, 0 }, { 1, 1, 0 }, ng);
		outColor = mix(outColor, { 1, 0, 1 }, nb);
	}
	
	//G
	else if (angleG < 1.04719) {
		outColor = mix({ 0, 1, 0 }, { 0, 1, 1 }, nr);
		outColor = mix(outColor, { 1, 1, 0 }, nb);
	}
	
	//B
	else if (angleB < 1.04719) {
		outColor = mix({ 0, 0, 1 }, { 0, 1, 1 }, ng);
		outColor = mix(outColor, { 1, 0, 1 }, nr);
	}
	vec_normalize(&outColor);

	outColor = min(outColor + ((vec3{ 1,1,1 } - outColor) * vec3 { dir, dir, dir }), vec3{ 1,1,1 });
	outColor = outColor * self->m_Ct.intensity;
	return outColor;
}

static vec2 f_颜色转坐标(const C_拾色盘* self, const vec3& rgb) {
	vec3 HSV = f_glsl_RGB_to_HSV(rgb);

	//mat2 rot = f_mat2_angle(M_角度转弧度(360 - HSV.x + 140));
	mat2 rot = f_mat2_angle(M_角度转弧度(360 - HSV.x - 30));
	vec2 coord = rot * vec2{-1,0};

	float32 l = self->mui_色轮->m_Size.x * 0.5f;
	coord = self->mui_色轮->m_Size * 0.5 + coord * (HSV.y * l);

	return coord;
}





static void f_当前颜色拾取器更新(const vec3& color) {
	std::cout<<"g当前打开列表组件:"<< g当前打开列表组件<<std::endl;
	if (g当前打开列表组件) {
		if (g当前打开列表组件->m_Value.m_Type == E_值类型::e_Type_RGB) {
			f_prop_Vec3(g当前打开列表组件->m_Value) = color;
		}
		else if (g当前打开列表组件->m_Value.m_Type == E_值类型::e_Type_RGBA) {

		}

		if (g当前打开列表组件->m_Value.m_UI->m_Update) {
			g当前打开列表组件->m_Value.m_UI->m_Update(g当前打开列表组件->m_Value);
		}
		f_ui_刷新vec编辑框文本绘制(C_颜色拾取器::g_色盘->mui_编辑框);
		
		//std::cout << "g当前打开列表组件->m_绘制属性更新 = " << g当前打开列表组件->m_绘制属性更新 << std::endl;
		g当前打开列表组件->m_绘制属性更新 = true;
		C_颜色拾取器::g_色盘->mui_编辑框->m_绘制属性更新 = true;

		if (g当前打开列表组件->m_Value.m_GPU缓存[0].m_Buf) {
			f_buf_Vec3_at(g当前打开列表组件->m_Value.m_GPU缓存[0], 0) = color;
			//((vec3*)(g当前打开列表组件->m_Value.m_GPU缓存.m_Buf->m_mappedPtr))[g当前打开列表组件->m_Value.m_GPU缓存.m_Mem] = color;
		}
	}
}

static bool on_拾色盘鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_Widget::g_是否打开了弹出窗口 = false;
	return false;
}

static bool on_拾色盘鼠标移出(C_Widget* self, const S_鼠标& 轮值) {
	C_拾色盘* box = static_cast<C_拾色盘*>(self->m_父部件);
	//创建线程
	f_widget_线程定时关闭弹出组件();
	
	return false;
}



static void on_拾色盘绘制(C_Widget* self, S_2D画布* 画布) {
	C_拾色盘* box = static_cast<C_拾色盘*>(self);

	box->m_背景绘制.m_图元.属性 = f_vg_gen属性(self->m_UIctx->m_Ctx);
	box->m_背景绘制.f_Draw(画布, box->m_背景绘制.m_图元, E_笔刷类型::e_单色填充);

	box->m_亮度.m_图元.属性 = box->m_背景绘制.m_图元.属性;
	box->m_亮度.f_Draw(画布, box->m_亮度.m_图元, E_笔刷类型::e_渐变);

	box->m_色轮.m_图元.属性 = box->m_背景绘制.m_图元.属性;
	box->m_色轮.f_Draw(画布, box->m_色轮.m_图元, E_笔刷类型::e_色轮);

	box->m_拾取点绘制.m_图元.属性 = box->m_背景绘制.m_图元.属性;
	box->m_拾取点绘制.f_Draw(画布, box->m_拾取点绘制.m_图元, E_笔刷类型::e_单色填充);

}

static void on_拾色盘布局(C_Widget* self, C_Widget** ws, uint32 num) {
	float32 编辑框高度 = 80;
	float32 边界宽度 = 6;
	float32 亮度滑块宽度 = 18;
	float32 盘大小 = DEF_Min(self->m_Size.y - 编辑框高度 - (边界宽度 * 3), self->m_Size.x - 亮度滑块宽度 - 边界宽度*4);
	
	//vec2 size = { self->m_Size.x - 28, self->m_Size.x - 28 };
	ws[0]->f_setPos({ 边界宽度, 边界宽度 });
	ws[0]->f_setSize({ 盘大小, 盘大小 });

	//亮度
	ws[1]->f_setPos({ (self->m_Size.x - 亮度滑块宽度 - 边界宽度), 边界宽度 });
	ws[1]->f_setSize({ 亮度滑块宽度, 盘大小 });

	//颜色值
	ws[2]->f_setPos({ 边界宽度, (self->m_Size.y - (编辑框高度 + 边界宽度) ) });
	ws[2]->f_setSize({ self->m_Size.x - 边界宽度*2, 编辑框高度 });
}

static void on_拾色盘变换(C_Widget* self) {
	C_拾色盘* box = static_cast<C_拾色盘*>(self);
	C_颜色拾取器* 颜色拾取器 = static_cast<C_颜色拾取器*>(self->m_父部件);

	auto e = self->f_get更新部件();


	S_2D顶点属性 属性 = { {1.0f, 1.0f} };
	属性.m_偏移 = {};
	属性.m_渐变数量 = 0;
	属性.m_渐变数量 = 0;



	box->m_背景绘制.f_alloc(2);
	mat3X2 mat;

	mat.row0 = { 0, 0 };
	mat.row1 = self->m_Size;
	mat.row2 = { 10, 0 };
	box->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_暗黑, S_Widget预设图元::m_圆角矩形);

	mat.row0 = { 1,1 };
	mat.row1 = self->m_Size-3;
	mat.row2 = { 10, 0 };
	box->m_背景绘制.f_set单色填充(1, mat, S_UI主题::uic_面板背景, S_Widget预设图元::m_圆角矩形);
	


	{
		C_滚动条* 滚动条 = static_cast<C_滚动条*>(e.m_W[1]);

		
		box->m_亮度.f_alloc(2);
		mat.row0 = 滚动条->m_Pos;
		mat.row1 = 滚动条->m_Size;
		mat.row2 = { 8, 0 };
		S_LineProp 渐变 = { 0, f_PackData4X8({0,0,0,255}), f_PackData4X8({0,0,0,255}) };
		box->m_亮度.f_set单色线(0, mat, 渐变, S_Widget预设图元::m_圆角矩形);
		mat.row0 = 滚动条->m_Pos + 2;
		mat.row1 = 滚动条->m_Size - 4;
		mat.row2 = { 6, 0 };
		渐变 = { 0, f_PackData4X8({255,255,255,255}), f_PackData4X8({0,0,0,255}) };
		box->m_亮度.f_set单色线(1, mat, 渐变, S_Widget预设图元::m_圆角矩形);


		box->m_拾取点绘制.f_alloc(4);
		mat.row0 = 滚动条->m_Pos + 滚动条->m_滑块->m_Pos;
		mat.row1 = { 滚动条->m_滑块->m_Size.x, 滚动条->m_滑块->m_Size.x };
		mat.row2 = { 8, 0 };
		box->m_拾取点绘制.f_set单色填充(0, mat, { 0,0,0,255 }, S_Widget预设图元::m_圆角矩形);

		mat.row0 = 滚动条->m_Pos + 滚动条->m_滑块->m_Pos + 2;
		mat.row1 = vec2{ 滚动条->m_滑块->m_Size.x, 滚动条->m_滑块->m_Size.x } - 4;
		mat.row2 = { 6, 0 };
		box->m_拾取点绘制.f_set单色填充(1, mat, { 255,255,255,255 }, S_Widget预设图元::m_圆角矩形);


		mat.row0 = box->m_拾取坐标;
		mat.row1 = vec2{ 10, 10 };
		mat.row2 = { 0, 0 };
		box->m_拾取点绘制.f_set单色填充(2, mat, S_UI主题::uic_暗黑, S_Widget预设图元::m_圆形);

		mat.row0 = box->m_拾取坐标 + 1;
		mat.row1 = vec2{ 8, 8 };
		mat.row2 = { 0, 0 };
		box->m_拾取点绘制.f_set单色填充(3, mat, { 255,255,255,255 }, S_Widget预设图元::m_圆形);
	}


	
	S_LineProp 渐变 = { box->m_Ct.intensity, f_PackData4X8({0,0,0,255}), f_PackData4X8({0,0,0,255}) };

	box->m_色轮.f_alloc(1);
	mat.row0 = e.m_W[0]->m_Pos;
	mat.row1 = e.m_W[0]->m_Size;
	mat.row2 = { 10, 0 };
	box->m_色轮.f_set单色线(0, mat, 渐变, S_Widget预设图元::m_圆形);

	//std::cout<<"box->m_Ct.intensity = " << box->m_Ct.intensity << std::endl;
	return;
	box->m_Ct.color = { 1,1,1 };
	vec2 size = e.m_W[0]->m_Size * 0.5f;
	box->m_Ct.coord.x = (box->m_拾取坐标.x - size.x) / size.x;
	box->m_Ct.coord.y = (box->m_拾取坐标.y - size.y) / size.y;
	//box->m_Ct.intensity = 0.5;
	//box->m_色轮.f_set色轮(0, mat, S_Widget预设图元::m_矩形, box->m_Ct);
	


}



//static bool g开启拾色 = false;
//static bool on_色盘鼠标按下(C_Widget* self, const E_鼠标按钮& 按钮) {
//	g开启拾色 = true;
//	C_拾色盘* box = static_cast<C_拾色盘*>(self->m_父部件);
//	box->m_拾取坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
//	vec3 color = f_坐标转颜色(box, box->m_拾取坐标, self->m_Size);
//
//	box->m_拾取坐标.x -= 5;
//	box->m_拾取坐标.y -= 5;
//	box->m_绘制属性更新 = true;
//
//	f_当前颜色拾取器更新(color);
//	
//	return true;
//}
//static bool on_色盘鼠标放开(C_Widget* self, const E_鼠标按钮& 按钮) {
//	g开启拾色 = false;
//	return true;
//}
//static bool on_色盘鼠标移动(C_Widget* self, const ivec4& value) {
//	if (g开启拾色) {
//		C_拾色盘* box = static_cast<C_拾色盘*>(self->m_父部件);
//		box->m_拾取坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
//
//		vec2 方向 = self->m_Size * 0.5 - box->m_拾取坐标;
//		float32 len = vec_normalize(&方向);
//
//		if (len > self->m_Size.x * 0.5) {
//			box->m_拾取坐标 = (方向 * self->m_Size.x * 0.5) + self->m_Pos;
//		}
//
//		vec3 color = f_坐标转颜色(box, box->m_拾取坐标, self->m_Size);
//
//		box->m_拾取坐标.x -= 5;
//		box->m_拾取坐标.y -= 5;
//		box->m_绘制属性更新 = true;
//
//		f_当前颜色拾取器更新(color);
//	}
//	return true;
//}


static E_事件是否传递 on_色盘手柄开始拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	
	C_拾色盘* box = static_cast<C_拾色盘*>(self->m_父部件);
	box->m_拾取坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
	vec3 color = f_坐标转颜色(box, box->m_拾取坐标, self->m_Size);

	box->m_绘制属性更新 = true;

	f_当前颜色拾取器更新(color);

	return E_事件是否传递::e_事件传递_终止;
}
static E_事件是否传递 on_色盘手柄拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_拾色盘* box = static_cast<C_拾色盘*>(self->m_父部件);
	box->m_拾取坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);

	vec2 方向 = self->m_Size * 0.5 - box->m_拾取坐标;
	float32 len = vec_normalize(&方向);

	if (len > self->m_Size.x * 0.5) {
		box->m_拾取坐标 = (self->m_Size * 0.5) - (方向 * self->m_Size.x * 0.5);
	}

	vec3 color = f_坐标转颜色(box, box->m_拾取坐标, self->m_Size);
	
	box->m_绘制属性更新 = true;
	box->mui_编辑框->m_绘制属性更新 = true;

	f_当前颜色拾取器更新(color);
	return E_事件是否传递::e_事件传递_终止;
}
static bool on_色盘手柄结束拖拽(C_Widget* self, C_Widget* 拾取的部件, S_拖放数据& data) {
	
	return true;
}



static void on_颜色亮度滑块条更新(C_Widget* self, float32 v) {
	C_拾色盘* 颜色拾取器 = static_cast<C_拾色盘*>(self->m_父部件);
	颜色拾取器->m_Ct.intensity = 1 + v;
	vec3 color = f_坐标转颜色(颜色拾取器, 颜色拾取器->m_拾取坐标, 颜色拾取器->mui_色轮->m_Size);
	f_当前颜色拾取器更新(color);

	颜色拾取器->m_绘制属性更新 = true;
}

C_拾色盘::C_拾色盘(S_UI创建环境& ctx, S_Props& prop, E_颜色模式 模式) : C_Widget(&ctx) {
	mf_DrawFun = on_拾色盘绘制;
	mf_布局Fun = on_拾色盘布局;
	mf_变换修改 = on_拾色盘变换;

	m_Ct.intensity = 1;
	m_Ct.coord.x;
	

	mui_色轮 = new C_Widget;
	f_添加子组件(mui_色轮);
	//mui_色轮->mf_鼠标按键按下 = on_色盘鼠标按下;
	//mui_色轮->mf_鼠标按键放开 = on_色盘鼠标放开;
	//mui_色轮->mf_鼠标移动 = on_色盘鼠标移动;
	mui_色轮->mf_拖拽 = on_色盘手柄拖拽;
	mui_色轮->mf_开始拖拽 = on_色盘手柄开始拖拽;
	mui_色轮->mf_结束拖拽 = on_色盘手柄结束拖拽;

	C_滚动条* 滚动条 = new C_滚动条(ctx, E_方向::e_纵向);
	滚动条->f_映射值指针(&m_Ct.intensity);
	滚动条->f_set值范围({1,0});
	滚动条->mf_滑块滚动回调 = on_颜色亮度滑块条更新;
	滚动条->m_滑块自适应大小 = false;
	f_添加子组件(滚动条);


	if (prop.m_Type == E_值类型::e_Type_RGB) {
		mui_编辑框 = new C_Vec(E_方向::e_纵向, prop, ctx);
	}
	else if (prop.m_Type == E_值类型::e_Type_RGBA) {
		
	}
	assert(mui_编辑框);
	f_添加子组件(mui_编辑框);

	f_setSize({ 220, 220+64 });

	m_拾取坐标 = { 110,110 };
}

C_拾色盘::~C_拾色盘() {
}









static void on_拾色器绘制(C_Widget* self, S_2D画布* 画布) {
	C_颜色拾取器* box = static_cast<C_颜色拾取器*>(self);

	//box->m_背景绘制.m_属性 = f_vg_gen属性(*self->m_UIctx);
	box->m_背景绘制.m_图元.属性 = f_vg_gen属性(self->m_UIctx->m_Ctx);
	box->m_背景绘制.f_Draw(画布, box->m_背景绘制.m_图元, E_笔刷类型::e_单色填充);

}

static void on_拾色器布局(C_Widget* self, C_Widget** ws, uint32 num) {
	
}

static void on_拾色器变换(C_Widget* self) {
	C_颜色拾取器* box = static_cast<C_颜色拾取器*>(self);

	box->m_背景绘制.f_alloc(1);

	mat3X2 mat;
	mat.row0 = { 0,0 };
	mat.row1 = self->m_Size;
	mat.row2 = { 6, 0 };
	box->m_背景绘制.f_set单色填充(0, mat, f_vec3_to_RGBA(f_prop_Vec3(box->m_Value)), S_Widget预设图元::m_圆角矩形);

}

static bool on_打开拾色盘(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_颜色拾取器* box = static_cast<C_颜色拾取器*>(self);
	
	g当前打开列表组件 = box;

	f_widget_顶层窗口_pop(0);
	f_widget_弹出顶层窗口(box->g_色盘);

	vec2 pos = self->m_GlobalLoc;
	pos.y -= (box->g_色盘->m_Size.y + self->m_Size.y);
	pos.x += self->m_Size.x;
	pos = f_widget_弹出窗口坐标矫正(box->g_色盘, pos);

	box->g_色盘->f_setPos(pos);
	f_widget_单个部件裁剪(box->g_色盘, { pos.x - 1, pos.y - 1, pos.x + box->g_色盘->m_Size.x + 3, pos.y + box->g_色盘->m_Size.y + 3 }, {});
	box->g_色盘->m_绘制属性更新 = true;


	f_ui_设置vec编辑框引用值(box->g_色盘->mui_编辑框, box->m_Value);

	vec3 rgb = f_prop_Vec3(box->m_Value);
	box->g_色盘->m_拾取坐标 = f_颜色转坐标(box->g_色盘, rgb);

	return true;
}

C_颜色拾取器::C_颜色拾取器(S_UI创建环境& ctx, S_Props& prop, E_颜色模式 模式) : C_Widget(&ctx) {
	m_Value = prop;
	mf_DrawFun = on_拾色器绘制;
	mf_变换修改 = on_拾色器变换;
	mf_鼠标按键点击 = on_打开拾色盘;

	f_setSize({ 50, 20 });

	if (!g_色盘) {
		g_色盘 = new C_拾色盘(ctx, prop, 模式);
		g_色盘->mf_鼠标进入 = on_拾色盘鼠标进入;
		g_色盘->mf_鼠标离开 = on_拾色盘鼠标移出;
	}
	
}

C_颜色拾取器::~C_颜色拾取器() {
}


C_Widget* f_ui_创建拾色器(S_UI创建环境& ctx, S_Props& prop) {
	C_颜色拾取器* box = new C_颜色拾取器(ctx, prop, E_颜色模式::e_颜色模式_RGBA);
	return box;
}

void f_ui_拾色器绑定属性(C_Widget* self, S_Props& prop) {
	C_颜色拾取器* box = static_cast<C_颜色拾取器*>(self);
	box->m_Value = prop;
}



